import { Socket } from 'socket.io';
import { Dept } from './Dept';
import { Game } from './Game';
import { CardPool } from './CardPool';
import { logger } from '../utils/logger';
import { events } from '../utils/events';
import { TurnManager } from './Turn';
import { GameEndRegistry } from '../registry/GameEndRegistry';
import { CardEvent } from './CardEvent';

export class Room {
	constructor(
		public game: Game,
		public roomId: string,
		public owner: string = '',
	) {
		this.pools = new CardPool(this);
		events.emit('roomInit', this);
		this.turns = new TurnManager(Object.keys(this.depts));
	}
	// 全局卡池
	pools: CardPool;
	// 回合计数
	turns: TurnManager;
	// 游戏状态
	isStartGame: boolean = false;
	// 部门数据
	depts: Record<string, Dept> = {};
	/**
	 * 游戏开始
	 * @param socket
	 * @returns
	 */
	start(socket: Socket): void {
		const dept = this.getDeptByPlayerId(socket.id);
		if (!dept) return;

		if (!this.isStartGame) {
			// 如果未开始游戏
			if (this.owner == '' || this.owner == socket.id) {
				events.emit('gameStart', this);
				this.turnStart();
				this.send('showSection', '#game');
			}
		} else {
			// 如果已开始游戏
			const dept = this.getDeptByPlayerId(socket.id);
			if (dept) {
				this.updateData();
				this.updateDept();
				this.send('showSection', '#game', socket);
			}
		}
	}

	/**
	 * 打牌
	 * @param playerId
	 * @param index
	 * @returns
	 */
	playCard(playerId: string, index: number, target: string) {
		if (!this.isStartGame) return;
		const dept = this.getDept(this.turns.current());
		if (!dept) return;

		if (dept.playerId != playerId) {
			const socket = this.game.getPlayerSocket(playerId);
			if (socket) this.send('message', '现在不是你的回合!', socket);
			return;
		}

		CardEvent.useCard(this, dept.deptId, index, target);
		logger.info(`PlayCard: ${playerId} ${index} ${target}`);
		if (dept.round) this.turnEnd(dept);
		this.updateDept();
	}

	// 回合开始时
	turnStart() {
		logger.info('TurnStart');
		const message = GameEndRegistry.checkAll(this);
		if (message) {
			this.send('message', message);
			this.send('endGame', {});
			this.isStartGame = false;
			return;
		}

		const dept = this.getDept(this.turns.current());
		if (!dept) return;
		this.send('message', `第${Math.floor(this.turns.turn)}回合`);
		this.send('message', `现在是${dept.name}的回合`);
		events.emit('turnStart', this, dept.deptId);

		this.updateData();
		this.updateDept();

		if (dept.isAI) dept.ai.turn(this);
	}

	// 回合结束时
	turnEnd(dept: Dept) {
		logger.info('TurnEnd');
		dept.round = false;
		events.emit('turnEnd', this, dept.deptId);
		this.turnStart();
	}

	addDept(dept: Dept) {
		this.depts[dept.deptId] = dept;
		logger.info(`RegisterDept: ${dept.deptId}`);
	}

	send(name: string, data: any, socket?: Socket) {
		if (socket) {
			// 发送给指定前端
			socket.emit(name, data);
		} else {
			// 发送给所有前端
			this.game.io.to(this.roomId).emit(name, data);
		}
	}

	getDeptByPlayerId(playerId: string): Dept | undefined {
		for (const deptId in this.depts) {
			const dept = this.depts[deptId];
			if (dept.playerId === playerId) return dept;
		}
		return undefined;
	}

	getDept(deptId: string): Dept | undefined {
		return this.depts[deptId];
	}

	updateDept() {
		for (const deptId in this.depts) {
			const dept = this.depts[deptId];
			const socket = this.game.getPlayerSocket(dept.playerId);
			if (socket) this.send('deptUpdate', dept.toClient(this), socket);
		}
	}

	updateData() {
		const deptData: Record<string, Record<string, string>> = {};
		for (const deptId in this.depts) {
			const dept = this.depts[deptId];
			// 部门数据
			const data: Record<string, any> = {};
			// 部门玩家
			data.isAI = dept.isAI;
			// 部门玩家
			data.playerId = dept.playerId;
			// 部门玩家
			data.playerName = this.game.getPlayerName(dept.playerId);
			// 部门势力
			data.power = dept.power;
			// 部门图标
			data.icon = dept.icon;
			// 部门名称
			data.name = dept.name;
			// 部门数据
			deptData[deptId] = data;
		}
		this.send('dataUpdate', deptData);
	}
}
